package com.gjp.etfweb.policys;

import com.gjp.etfweb.abstracts.AbstractPolicy;
import com.gjp.etfweb.bean.FundHistory;
import com.gjp.etfweb.common.Constant;
import com.gjp.etfweb.form.QueryForm;
import com.gjp.etfweb.utils.CommonUtils;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

public class BoboPolicy extends AbstractPolicy {

    // 入场时间
    public Date startTime;

    @Override
    public void init(QueryForm queryParam) {
        super.init(queryParam);
        startTime = null;
    }

    @Override
    public Map<String, BigDecimal> buyPoint(FundHistory fundHistory) {
        Map<String, BigDecimal> buyAndShareMap = new HashMap<>();
        // 从父类获取查询参数
        BigDecimal buyAmount = queryParam.getBuyAmount();
        BigDecimal serviceChargeRate = queryParam.getServiceChargeRate();
        // 如果跌幅超过2% 就买入 单位金额，每多1% 就多买1单位
        BigDecimal increaseRate = fundHistory.getIncreaseRate();
        if (increaseRate.compareTo(BigDecimal.valueOf(-2)) < 0) {
            //计算买入多少单位金额
            BigDecimal factor = increaseRate
                    .add(BigDecimal.valueOf(2))
                    .divide(BigDecimal.valueOf(-1), 0, BigDecimal.ROUND_DOWN)
                    .add(BigDecimal.ONE);
            BigDecimal actualBuyAmount = buyAmount.multiply(factor);
            // 计算定投份额 (定投金额/1+手续费/基金净值)
            BigDecimal buyShare = actualBuyAmount
                    .divide(BigDecimal.ONE.add(serviceChargeRate), Constant.DECIMAL_POINT, BigDecimal.ROUND_HALF_UP)
                    .divide(fundHistory.getNetWorth(), Constant.DECIMAL_POINT, BigDecimal.ROUND_HALF_UP);
            // 记录购买金额和份额
            buyAndShareMap.put("buy", actualBuyAmount);
            buyAndShareMap.put("share", buyShare);
        }
//        System.out.println("买入：");
//        printDetails(getFundDetails(fundHistory));
        return buyAndShareMap;
    }

    @Override
    public void processBusiness(FundHistory fundHistory) {
        // 有持仓
        if (totalShare.compareTo(BigDecimal.ZERO) > 0) {
            // 计算收益率
            processRate(fundHistory);
            // 执行止盈策略
            sellPoint(fundHistory);
        }
        // 历史当天的 涨跌幅
        BigDecimal increaseRate = fundHistory.getIncreaseRate();
        // 1 如果当天下跌
        if (increaseRate.compareTo(BigDecimal.ZERO) < 0) {
            // 初始值
            share = BigDecimal.ZERO;
            buy = BigDecimal.ZERO;
            // 执行买入策略
            Map<String, BigDecimal> buyAndShareMap = buyPoint(fundHistory);
            if (!CollectionUtils.isEmpty(buyAndShareMap)) {
                // 记录入场时间
                if (Objects.isNull(startTime)) {
                    startTime = fundHistory.getDate();
                }
                buy = buyAndShareMap.get("buy");
                share = buyAndShareMap.get("share");
            }
            // 统计累计份额和累计金额
            totalShare = totalShare.add(share);
            totalBuyAmount = totalBuyAmount.add(buy);
            // 计算平均成本 (累计定投金额/累计定投份额)
            if (totalShare.compareTo(BigDecimal.ZERO) > 0) {
                averageCost = totalBuyAmount.divide(totalShare, Constant.DECIMAL_POINT, BigDecimal.ROUND_HALF_UP);
            }
        }
        // 计算投资天数
        if (!Objects.isNull(startTime)) {
            totalDay = BigDecimal.valueOf(CommonUtils.intervalDays(startTime, fundHistory.getDate()));
        }
    }

    /**
     * 计算指标数据
     *
     * @param fundHistory
     */
    @Override
    public void processRate(FundHistory fundHistory) {

        // 计算入场时间到现在的天数  即投资天数
        BigDecimal dayNum = BigDecimal.valueOf(
                CommonUtils.intervalDays(
                        startTime,
                        fundHistory.getDate()
                )
        );

        // 1. 先算历史收益
        // 定投收益 (基金净值-平均成本)*累计定投份额，或总市值-累计定投金额。
        earningsAmount = fundHistory.getNetWorth().subtract(averageCost).multiply(totalShare);
        // 定投收益率 (定投收益/累计定投金额)
        if (totalShare.compareTo(BigDecimal.ZERO) > 0) {
            earningsRate = earningsAmount.divide(totalBuyAmount, Constant.DECIMAL_POINT, BigDecimal.ROUND_HALF_UP);
        }
        // 年化收益率=（投资内收益/本金）/（投资天数/365）×100%
        if (totalBuyAmount.compareTo(BigDecimal.ZERO) > 0) {
            // 计算投资天数
            BigDecimal investmentDays = dayNum.divide(BigDecimal.valueOf(365), BigDecimal.ROUND_HALF_UP);
            if (investmentDays.compareTo(BigDecimal.ZERO) == 0) {
                //最小等于1
                investmentDays = BigDecimal.ONE;
            }
            yearEarningsRate = earningsAmount
                    .divide(totalBuyAmount, Constant.DECIMAL_POINT, BigDecimal.ROUND_HALF_UP)
                    .divide(investmentDays, Constant.DECIMAL_POINT, BigDecimal.ROUND_HALF_UP);
        }
    }

    /**
     * 卖出策略 默认清仓
     *
     * @param fundHistory
     * @return
     */
    @Override
    public boolean sellPoint(FundHistory fundHistory) {
        // 判断是否达到止盈点，如果达到止盈点，则停止买入，开始止盈
        if (yearEarningsRate.compareTo(queryParam.getStopPoint()) >= 0) {
            // 超出止盈点，全部卖出
            totalCost = totalCost.add(totalBuyAmount);
            totalProfit = totalProfit.add(totalShare.multiply(fundHistory.getNetWorth()));
            // 清空总份额
            totalShare = BigDecimal.ZERO;
            totalBuyAmount = BigDecimal.ZERO;
            totalDay = BigDecimal.ZERO;
            averageCost = BigDecimal.ZERO;
            // 清空收益
            earningsRate = BigDecimal.ZERO;
            yearEarningsRate = BigDecimal.ZERO;
            earningsAmount = BigDecimal.ZERO;

            stopNum++;
            startTime = null;
            return true;
        }
        return false;
    }

}
